library ieee;
use ieee.std_logic_1164.all;

entity ShiftRegister32 is
	port (
	  --hold disables the load function
		clk, clr, load, hold, serialIn : in bit;
		inVec : in bit_vector(31 downto 0);
		outVec : out bit_vector(31 downto 0)
	);
end entity ShiftRegister32;
 
architecture STRUCTURAL of ShiftRegister32 is

component shiftRegSelectLogic  

	port(clk, clr, load, hold : in bit;
		z1, z2 : out bit
	);
	
end component;

component shiftRegModule

	port (clk, dataIn, QInPrev, selectH, selectL: in bit;
		R : out bit
	);
	
end component;

for all : shiftRegSelectLogic use entity work.shiftRegSelectLogic(RTL);
for all : shiftRegModule use entity work.shiftRegModule(STRUCTURAL);	
	
signal moduleConnectVec : bit_vector(32 downto 0);
signal preOutVec : bit_vector(31 downto 0);
signal selectVec : bit_vector(1 downto 0);	
	
begin

	selectLogic : shiftRegSelectLogic 
		port map(clk, clr, load, hold, 
			selectVec(1), selectVec(0)			
		);
	
	moduleConnectVec(32) <= serialIn; -- first bit is serial in

	G1 : for i in 31 downto 0 generate
	module : shiftRegModule
		port map (			
			clk, inVec(i), moduleConnectVec(i + 1),
			 selectVec(1), selectVec(0), preOutVec(i)
		);
		
		moduleConnectVec(i) <= preOutVec(i);
		
	end generate g1;
  
  outVec <= preOutVec;

end architecture STRUCTURAL;

architecture RTL of ShiftRegister32 is
    
    signal tempOut : bit_vector(31 downto 0);
    
    begin
    
    outVec <= tempOut;
    
    process(clk)
    begin
 		if (clk = '1' AND not clk'STABLE) then
 		    if (clr = '0') then
 		    	 tempOut <= "00000000000000000000000000000000";   
 		 	end if;
 		    if (hold = '0' and clr = '1') then
 		    	tempOut(30 downto 0) <= tempOut(31 downto 1);
 		    	tempOut(31) <= serialIn;
 		    end if;
 		    if (load = '1' and clr = '1') then
 		    	    tempOut <= inVec;
 		    end if;
 		 end if;
    end process;
end rtl;

